/*
Copyright (C) 1996-1997 Id Software, Inc.

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 3
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

*/

// defines some simple default geometric shapes
#include "quakedef.h"

// beware - this sphere was created by D3DX and is oriented for an LH coord system; I'll make a better one later
static const float sphereverts[] = {
	0.000000, 0.000000, 1.000000, 0.000000, 0.309017, 0.951057, 0.181636, 0.250000, 0.951057, 0.293893, 0.095491, 0.951057, 0.293893,
	-0.095492, 0.951057, 0.181636, -0.250000, 0.951057, -0.000000, -0.309017, 0.951057, -0.181636, -0.250000, 0.951057, -0.293893, -0.095492,
	0.951057, -0.293893, 0.095492, 0.951057, -0.181636, 0.250000, 0.951057, 0.000000, 0.587785, 0.809017, 0.345491, 0.475528, 0.809017,
	0.559017, 0.181636, 0.809017, 0.559017, -0.181636, 0.809017, 0.345491, -0.475528, 0.809017, -0.000000, -0.587785, 0.809017, -0.345492,
	-0.475528, 0.809017, -0.559017, -0.181636, 0.809017, -0.559017, 0.181636, 0.809017, -0.345491, 0.475528, 0.809017, 0.000000, 0.809017,
	0.587785, 0.475528, 0.654509, 0.587785, 0.769421, 0.250000, 0.587785, 0.769421, -0.250000, 0.587785, 0.475528, -0.654509, 0.587785,
	-0.000000, -0.809017, 0.587785, -0.475528, -0.654508, 0.587785, -0.769421, -0.250000, 0.587785, -0.769421, 0.250000, 0.587785,
	-0.475528, 0.654509, 0.587785, 0.000000, 0.951057, 0.309017, 0.559017, 0.769421, 0.309017, 0.904509, 0.293893, 0.309017, 0.904508,
	-0.293893, 0.309017, 0.559017, -0.769421, 0.309017, -0.000000, -0.951057, 0.309017, -0.559017, -0.769421, 0.309017, -0.904508,
	-0.293893, 0.309017, -0.904508, 0.293893, 0.309017, -0.559017, 0.769421, 0.309017, 0.000000, 1.000000, -0.000000, 0.587785, 0.809017,
	-0.000000, 0.951057, 0.309017, -0.000000, 0.951056, -0.309017, -0.000000, 0.587785, -0.809017, -0.000000, -0.000000, -1.000000,
	-0.000000, -0.587785, -0.809017, -0.000000, -0.951056, -0.309017, -0.000000, -0.951056, 0.309017, -0.000000, -0.587785, 0.809017,
	-0.000000, 0.000000, 0.951056, -0.309017, 0.559017, 0.769421, -0.309017, 0.904508, 0.293893, -0.309017, 0.904508, -0.293893, -0.309017,
	0.559017, -0.769421, -0.309017, -0.000000, -0.951056, -0.309017, -0.559017, -0.769421, -0.309017, -0.904508, -0.293893, -0.309017,
	-0.904508, 0.293893, -0.309017, -0.559017, 0.769421, -0.309017, 0.000000, 0.809017, -0.587785, 0.475528, 0.654509, -0.587785, 0.769421,
	0.250000, -0.587785, 0.769421, -0.250000, -0.587785, 0.475528, -0.654509, -0.587785, -0.000000, -0.809017, -0.587785, -0.475528,
	-0.654508, -0.587785, -0.769421, -0.250000, -0.587785, -0.769421, 0.250000, -0.587785, -0.475528, 0.654509, -0.587785, 0.000000,
	0.587785, -0.809017, 0.345491, 0.475528, -0.809017, 0.559017, 0.181636, -0.809017, 0.559017, -0.181636, -0.809017, 0.345491,
	-0.475528, -0.809017, -0.000000, -0.587785, -0.809017, -0.345492, -0.475528, -0.809017, -0.559017, -0.181636, -0.809017, -0.559017,
	0.181636, -0.809017, -0.345491, 0.475528, -0.809017, 0.000000, 0.309017, -0.951057, 0.181636, 0.250000, -0.951057, 0.293892, 0.095491,
	-0.951057, 0.293892, -0.095491, -0.951057, 0.181635, -0.250000, -0.951057, -0.000000, -0.309017, -0.951057, -0.181636, -0.250000,
	-0.951057, -0.293892, -0.095491, -0.951057, -0.293892, 0.095491, -0.951057, -0.181635, 0.250000, -0.951057, 0.000000, 0.000000, -1.000000
};

static const unsigned short sphereindexes[] = {
	0, 2, 1, 0, 3, 2, 0, 4, 3, 0, 5, 4, 0, 6, 5, 0, 7, 6, 0, 8, 7, 0, 9, 8, 0, 10, 9, 0, 1, 10, 1, 2, 11, 2, 12, 11, 2, 3, 12, 3, 13, 12, 3,
	4, 13, 4, 14, 13, 4, 5, 14, 5, 15, 14, 5, 6, 15, 6, 16, 15, 6, 7, 16, 7, 17, 16, 7, 8, 17, 8, 18, 17, 8, 9, 18, 9, 19, 18, 9, 10, 19, 10,
	20, 19, 10, 1, 20, 1, 11, 20, 11, 12, 21, 12, 22, 21, 12, 13, 22, 13, 23, 22, 13, 14, 23, 14, 24, 23, 14, 15, 24, 15, 25, 24, 15, 16, 25,
	16, 26, 25, 16, 17, 26, 17, 27, 26, 17, 18, 27, 18, 28, 27, 18, 19, 28, 19, 29, 28, 19, 20, 29, 20, 30, 29, 20, 11, 30, 11, 21, 30, 21,
	22, 31, 22, 32, 31, 22, 23, 32, 23, 33, 32, 23, 24, 33, 24, 34, 33, 24, 25, 34, 25, 35, 34, 25, 26, 35, 26, 36, 35, 26, 27, 36, 27, 37,
	36, 27, 28, 37, 28, 38, 37, 28, 29, 38, 29, 39, 38, 29, 30, 39, 30, 40, 39, 30, 21, 40, 21, 31, 40, 31, 32, 41, 32, 42, 41, 32, 33, 42,
	33, 43, 42, 33, 34, 43, 34, 44, 43, 34, 35, 44, 35, 45, 44, 35, 36, 45, 36, 46, 45, 36, 37, 46, 37, 47, 46, 37, 38, 47, 38, 48, 47, 38,
	39, 48, 39, 49, 48, 39, 40, 49, 40, 50, 49, 40, 31, 50, 31, 41, 50, 41, 42, 51, 42, 52, 51, 42, 43, 52, 43, 53, 52, 43, 44, 53, 44, 54,
	53, 44, 45, 54, 45, 55, 54, 45, 46, 55, 46, 56, 55, 46, 47, 56, 47, 57, 56, 47, 48, 57, 48, 58, 57, 48, 49, 58, 49, 59, 58, 49, 50, 59,
	50, 60, 59, 50, 41, 60, 41, 51, 60, 51, 52, 61, 52, 62, 61, 52, 53, 62, 53, 63, 62, 53, 54, 63, 54, 64, 63, 54, 55, 64, 55, 65, 64, 55,
	56, 65, 56, 66, 65, 56, 57, 66, 57, 67, 66, 57, 58, 67, 58, 68, 67, 58, 59, 68, 59, 69, 68, 59, 60, 69, 60, 70, 69, 60, 51, 70, 51, 61,
	70, 61, 62, 71, 62, 72, 71, 62, 63, 72, 63, 73, 72, 63, 64, 73, 64, 74, 73, 64, 65, 74, 65, 75, 74, 65, 66, 75, 66, 76, 75, 66, 67, 76,
	67, 77, 76, 67, 68, 77, 68, 78, 77, 68, 69, 78, 69, 79, 78, 69, 70, 79, 70, 80, 79, 70, 61, 80, 61, 71, 80, 71, 72, 81, 72, 82, 81, 72,
	73, 82, 73, 83, 82, 73, 74, 83, 74, 84, 83, 74, 75, 84, 75, 85, 84, 75, 76, 85, 76, 86, 85, 76, 77, 86, 77, 87, 86, 77, 78, 87, 78, 88,
	87, 78, 79, 88, 79, 89, 88, 79, 80, 89, 80, 90, 89, 80, 71, 90, 71, 81, 90, 81, 82, 91, 82, 83, 91, 83, 84, 91, 84, 85, 91, 85, 86, 91,
	86, 87, 91, 87, 88, 91, 88, 89, 91, 89, 90, 91, 90, 81, 91
};


#define X 0.525731112119133606
#define Z 0.850650808352039932

static const float icosverts[] = {
	-X, 0, Z, X, 0, Z, -X, 0, -Z, X, 0, -Z,    
	0, Z, X, 0, Z, -X, 0, -Z, X, 0, -Z, -X,    
	Z, X, 0, -Z, X, 0, Z, -X, 0, -Z, -X, 0 
};


static const unsigned short icosindexes[] = {
	0, 4, 1, 0, 9, 4, 9, 5, 4, 4, 5, 8, 4, 8, 1, 
	8, 10, 1, 8, 3, 10, 5, 3, 8, 5, 2, 3, 2, 7, 3, 
	7, 10, 3, 7, 6, 10, 7, 11, 6, 11, 0, 6, 0, 1, 6, 
	6, 1, 10, 9, 0, 11, 9, 11, 2, 9, 2, 5, 7, 2, 11
};


static const float boxverts[] = {
	-1.0, -1.0, 1.0, 1.0, -1.0, 1.0,
	1.0, 1.0, 1.0, -1.0, 1.0, 1.0,
	-1.0, -1.0, -1.0, 1.0, -1.0, -1.0,
	1.0, 1.0, -1.0, -1.0, 1.0, -1.0
};


static const unsigned short boxindexes[] = {
	0, 2, 1, 2, 0, 3, 3, 6, 2, 6, 3, 7,
	7, 5, 6, 5, 7, 4, 4, 1, 5, 1, 4, 0,
	4, 3, 0, 3, 4, 7, 1, 6, 5, 6, 1, 2
};


geo_t::geo_t (void)
{
	this->VertexBuffer = NULL;
	this->IndexBuffer = NULL;
	this->NumVertexes = 0;
	this->NumIndexes = 0;
}


void geo_t::Release (void)
{
	SAFE_RELEASE (this->VertexBuffer);
	SAFE_RELEASE (this->IndexBuffer);
	this->NumVertexes = 0;
	this->NumIndexes = 0;
}


void geo_t::CreateShape (const float *verts, int vertsize, const unsigned short *indexes, int indexsize)
{
	D3D10_SUBRESOURCE_DATA vbSrd = {verts, 0, 0};
	D3D10_SUBRESOURCE_DATA ibSrd = {indexes, 0, 0};

	D3D10_BUFFER_DESC vbDesc = {
		vertsize,
		D3D10_USAGE_IMMUTABLE,
		D3D10_BIND_VERTEX_BUFFER,
		0,
		0
	};

	D3D10_BUFFER_DESC ibDesc = {
		indexsize,
		D3D10_USAGE_IMMUTABLE,
		D3D10_BIND_INDEX_BUFFER,
		0,
		0
	};

	d3d_Device->CreateBuffer (&vbDesc, &vbSrd, &this->VertexBuffer);
	d3d_Device->CreateBuffer (&ibDesc, &ibSrd, &this->IndexBuffer);

	this->NumVertexes = vertsize / (sizeof (float) * 3);
	this->NumIndexes = indexsize / (sizeof (unsigned short));
}


void geo_t::CreateIcosahedron (void)
{
	this->CreateShape (icosverts, sizeof (icosverts), icosindexes, sizeof (icosindexes));
}


void geo_t::CreateSphere (void)
{
	this->CreateShape (sphereverts, sizeof (sphereverts), sphereindexes, sizeof (sphereindexes));
}


void geo_t::CreateBox (void)
{
	this->CreateShape (boxverts, sizeof (boxverts), boxindexes, sizeof (boxindexes));
}

